/*
 * building.cpp
 *
 *  Created on: 22/04/2012
 *      Author: alex
 */

#include <iostream>
#include <signal.h>
#include <assert.h>
#include <cstdlib>

#include "IPC/EventHandler.h"
#include "IPC/SignalHandler.h"
#include "IPC/LockFile.h"
#include "IPC/Semaphore.h"
#include "application/Building.h"

//ToDo: Sacar este define y guardar este valor en otro lugar.
#define AVERAGE_PASSENGER_WEIGHT 75.0

class SIGINT_Handler : public EventHandler
{
    private:
        Building *m_building;
    public:

        virtual ~SIGINT_Handler()
        {
        }

        SIGINT_Handler (): m_building(NULL)
        {
        }

        virtual int handleSignal ( int signum )
        {
        	std::cout << "Senial"<<std::endl;
            assert ( signum == SIGINT );

            if(m_building)
                m_building->stopSimulation();

            sleep(5);
        	std::cout << "Senial end"<<std::endl;
            return 0;
        }

        void setBuilding(Building *building)
        {
            m_building = building;
        }

};


using namespace std;

int main (int argc, char *argv[])
{
	if(argc < 5)
	{
		cout << "Invalid number of arguments"<<endl;
		cout << "Program must be called like this:"<<endl;
		cout << argv[0] <<" [floor ammount] [elevator speed] [simulation duration]"
		     << " [elevator max capacity] [log level]"<<endl;
		cout << "Ej:"<<endl<<argv[0]<<" 15 3 30 9 1"<<endl;
		exit(1);
	}

	CLogger::create("Building");
	int floorAmount = StringUtils:: StringToNumber<int>(argv[1]);
	float elevatorSpeed = StringUtils:: StringToNumber<float>(argv[2]);
	float simulationDuration = StringUtils:: StringToNumber<float>(argv[3]);
	float elevatorMaxCapacity = StringUtils:: StringToNumber<float>(argv[4]) * AVERAGE_PASSENGER_WEIGHT;
	int logLevel =LogLevelEnum::ERROR;
	int elevatorAmmount = 3;

	if(argc >= 6)
	 logLevel =  StringUtils:: StringToNumber<int>(argv[5]);

	CLogger::setLevel(logLevel);
	CLogger::log("Building started.",LogLevelEnum::DEBUG);
    Building building(floorAmount, elevatorSpeed, elevatorMaxCapacity,elevatorAmmount ,"/tmp/",argv[0]);
    SIGINT_Handler sigint_handler;

    sigint_handler.setBuilding(&building);

    //Registro los event handlers
    SignalHandler :: getInstance()->registerHandler ( SIGINT,&sigint_handler );

    building.startSimulation(simulationDuration);

    SignalHandler :: destroy();
    CLogger::log("Building terminated",LogLevelEnum::DEBUG);

    CLogger::destroy();
}
